import {
  initState
} from './state';
import {
  compileToRenderFunction
} from './compiler/index';
import {
  mountComponent
} from './lifecycle';

/**
 * initMixin函数
 * @param {*} Vue 构造函数
 */
function initMixin(Vue) {
  Vue.prototype._init = function (options) {
    const vm = this;

    vm.$options = options;

    /**
     console.log(vm);
     * Vue = {
     *   "$el": div#app,
     *   "$options": {
     *     "el": "#app",
     *     "template": "",
     *     "render": ƒ render(createElement)
     * }
     */
    initState(vm);
    // console.log(vm);

    //判断有没有el
    if (vm.$options.el) {
      // console.log(vm.$options.el); #app

      //$mount 挂载函数 Vue.prototype.$mount
      vm.$mount(vm.$options.el);
    }
  }

  Vue.prototype.$mount = function (el) {
    const vm = this,
      options = vm.$options;

    el = document.querySelector(el),
      vm.$el = el;

    console.log(vm);

    //如果用户没有写render函数
    if (!options.render) {
      console.log('User did not write render function!');
      let template = options.template;

      //如果用户没有写template字符串模板且el节点在
      if (!template && el) {
        //将整个el拿过来当作模板
        template = el.outerHTML;
      }

      //将template转为render函数
      //compileToRenderFunction函数负责：
      //1.编译成AST树
      //2.将AST树转换成render函数
      const render = compileToRenderFunction(template);

      //将返回出来的render函数挂载到options里
      options.render = render;

      /**
       * console.log(options);
       * {
       *   data: ƒ data(),
       *   el: "#app",
       *   render: ƒ anonymous( ),
       *   template: ""
       * }
       */
    }

    //其实vue的实例就是一个组件
    mountComponent(vm);

  }

}

export {
  initMixin
}